#include "GameplayState.h"

#include "MainMenuState.h"
#include "CreditsState.h"
#include "Entity.h"
#include "Player.h"
#include "Camera.h"
#include "TileEngine.h"
#include "Layer.h"
#include "Tile.h"

#include <time.h>

#include "../SGD Wrappers/SGD_GraphicsManager.h"
#include "../SGD Wrappers/SGD_InputManager.h"
#include "../SGD Wrappers/SGD_AudioManager.h"
#include "../SGD Wrappers/SGD_String.h"


GameplayState* GameplayState::GetInstance(void) {
	static GameplayState s_Instance;	// stored in global memory once
	return &s_Instance;
}

void GameplayState::Enter(void) {

		//	Seed random
	srand((unsigned int)time(nullptr));

		//	Load Audio
	m_win = SGD::AudioManager::GetInstance()->LoadAudio(L"resource/audio/ANM_WinSound.wav");
	m_lose = SGD::AudioManager::GetInstance()->LoadAudio(L"resource/audio/ANM_LoseSound.wav");

		//	Pause menu setup
	m_pause.m_PauseScreen = {
		256, 256,
		Game::GetInstance()->GetScreenWidth() - 256,
		Game::GetInstance()->GetScreenHeight() - 256
	};

		//	TileEngine	
	m_TileEngine = new TileEngine();
	m_TileEngine->LoadMap("testmap.xml");

		//	Player
	m_Player = new Player();
	m_Player->SetPosition(m_TileEngine->GetMapLayer()->GetStartTile()->GetWorldPosition());
	m_TileEngine->SetCamFocus(m_Player);
}

void GameplayState::Exit(void) {

	SGD::AudioManager* audio = SGD::AudioManager::GetInstance();

	//	Unload assets
	audio->UnloadAudio(m_win);
	audio->UnloadAudio(m_lose);

	m_pause.isPaused = false;

	//	Unload some more
	delete m_Player;
	delete m_TileEngine;
}

bool GameplayState::Update(float elapsedTime)	{

	SGD::InputManager* input = SGD::InputManager::GetInstance();


#pragma region Pause Menu
		//	Escape during pause
	if (input->IsKeyPressed(SGD::Key::Escape) == true && !m_pause.isPaused && !m_endgame.Losing) {
		m_pause.isPaused = true;
	}
	else if (input->IsKeyPressed(SGD::Key::Escape) == true && m_pause.isPaused) {
		m_pause.isPaused = false;
	}
		//	Enter during pause
	if (m_pause.isPaused && input->IsKeyPressed(SGD::Key::Enter) == true && m_pause.m_nCursor == 1
		&& !m_endgame.Losing){
		m_pause.isPaused = false;
	}
	else if (m_pause.isPaused && input->IsKeyPressed(SGD::Key::Enter) == true && m_pause.m_nCursor == 2){
		Game::GetInstance()->ChangeState(MainMenuState::GetInstance());
		return true;
	}
		//	Arrow keys during pause
	if (m_pause.isPaused && input->IsKeyPressed(SGD::Key::UpArrow)){

		if (m_pause.m_nCursor == 2)
			m_pause.m_nCursor = 1;
		else
			m_pause.m_nCursor = 2;
	}
	else if (m_pause.isPaused && input->IsKeyPressed(SGD::Key::DownArrow)){

		if (m_pause.m_nCursor == 2)
			m_pause.m_nCursor = 1;
		else
			m_pause.m_nCursor = 2;
	}
#pragma endregion


	if (!m_pause.isPaused){
		m_TileEngine->Update(elapsedTime);
		m_Player->SetCamOffset(m_TileEngine->GetCamera()->GetCameraOffset());
		m_Player->Update(elapsedTime, m_TileEngine->GetWorldSize(), m_TileEngine->GetMapLayer(), m_TileEngine->GetCamera()->GetCameraOffset());
	}
	return true;	// keep playing
}

void GameplayState::Render(float elapsedTime)	{

	SGD::GraphicsManager* graphics = SGD::GraphicsManager::GetInstance();

	m_TileEngine->Render();
	m_Player->Render();

#pragma region Pause Screen
	if (m_pause.isPaused) {
		graphics->DrawRectangle(m_pause.m_PauseScreen,
			SGD::Color(160, 160, 160), SGD::Color(0, 0, 0));

		// Use the game's font
		const BitmapFont* pFont = Game::GetInstance()->GetFont();

		// Display the level options centered at 1x scale
		pFont->Draw("Resume", { m_pause.m_PauseScreen.left + 150, m_pause.m_PauseScreen.top + 50 },
			1.0f, { 255, 0, 0 });
		pFont->Draw("Quit", { m_pause.m_PauseScreen.left + 150, m_pause.m_PauseScreen.top + 100 },
			1.0f, { 255, 0, 0 });


		if (m_pause.m_nCursor == 1)
			pFont->Draw("=       =", { m_pause.m_PauseScreen.left + 100, m_pause.m_PauseScreen.top + (50 * m_pause.m_nCursor) },
			1.0f, { 0, 255, 0 });

		else if (m_pause.m_nCursor == 2)
			pFont->Draw("=      =", { m_pause.m_PauseScreen.left + 100, m_pause.m_PauseScreen.top + (50 * m_pause.m_nCursor) },
			1.0f, { 0, 255, 0 });
	}
#pragma endregion

	else if (m_endgame.Winning == true){
		SGD::OStringStream losemessage;
		losemessage << "YOU WIN!";
		graphics->DrawString(losemessage.str().c_str(), { (1024 / 2) - 128, 64 }, SGD::Color(0, 255, 0));
	}
	else if (m_endgame.GameOver == true){
		SGD::OStringStream losemessage;
		losemessage << "GAME OVER!";
		graphics->DrawString(losemessage.str().c_str(), { (1024 / 2) - 128, 64 }, SGD::Color(244, 0, 0));
	}
}